#!/bin/bash
##################################################################################################
##  Purpose:HGDB INIT 
##  Author :syd
##  Created:2024-07-12
##  Version:2
##################################################################################################
# 1.日志输出格式
log(){
	LOGFILE=init_hgdb_$(date +"%Y%m%d").log
	LOGTYPE=$1
	NOW_TIME='['$(date +"%Y-%m-%d %H:%M:%S")']'
	case $LOGTYPE in
	ERROR)
	    echo -e "\033[31m$NOW_TIME [$1]$2\033[0m" 2>&1 | tee -a $LOGFILE;;
	INFO)
	    echo -e "\033[34m$NOW_TIME [$1]$2\033[0m" 2>&1 | tee -a $LOGFILE;;
	INPUT)
	    echo -e "\033[33m$NOW_TIME [$1]$2\033[0m" 2>&1 | tee -a $LOGFILE;;
	CMD)
		echo -e -n "\033[37m$NOW_TIME $2\n\033[0m" 2>&1 | tee -a $LOGFILE
		echo -e -n "\033[37m `$2`\n\033[0m" 2>&1 | tee -a $LOGFILE;;
	esac
}

# 2.磁盘环境检查
check_disk(){
	log CMD 'df -Th'
	log CMD 'fdisk -l'
	while [[ ! $t =~ [y,Y,n,N] ]]
	do
	read -p "是否需要挂载新磁盘【默认n】：" t
	log INFO "是否需要挂载新磁盘【默认n】，你选择${t:=n}。"
	case "$t" in
		Y|y)
			while [[ $cmd1 -eq 0 ]]
			do
			read -p "需要挂载的磁盘路径为【默认/dev/sdb】：" d
			log INFO "你选择挂载的磁盘路径为 ${d:=/dev/sdb}"
			cmd1=`fdisk -l|grep $d|wc -l`
			if [ $cmd1 -eq 0 ]
				then
					log ERROR "磁盘不存在，请重新输入"
			else
				log INFO "开始挂载磁盘……"
				fdisk $d
				mkfs.ext4 ${d}1
				UUID=`blkid|grep ${d}1|awk -F '"' '{print $2}'`
				
				if [ `grep $UUID /etc/fstab|wc -l` -eq 0 ]
					then
						echo "UUID=$UUID    /data     ext4    defaults  0 0" >> /etc/fstab
					else
						:
				fi
				
				if [ -d /data ]
				then
						:
				else
						mkdir -p /data
				fi
				mount -a
				df -Th
				log INFO "挂载磁盘成功。"
			fi
			done
			;;
		N|n)
			:
			;;
		*)
			log ERROR "只可输入n或y，请重新输入！"
	esac
	done
}

# 3.定义变量
def_var(){
	PGHOME=`find /opt -name hgdb-see-4.5.8`
	read -p "数据库数据目录【默认:/data/highgo/data】: " BPGDATA
	log INFO "你选择的数据库数据目录为：${BPGDATA:=/data/highgo/data}"
	read -p "数据库端口【默认:5866】: " PORT
	log INFO "你选择的数据库端口为：${PORT:=5866}"
	read -p "数据库备份目录【默认:/data/highgo/hgdbbak】: " BACK_DIR
	log INFO "你选择的数据库备份目录为：${BACK_DIR:=/data/highgo/hgdbbak}"
    PASSWORD="Hello@321"
	
	if [ -d $BACK_DIR ]
	then
			:
	else
		mkdir -p $BACK_DIR/{archive,dbbak}
	fi	
	
	ENV=`find /opt -name *dbenv*`
	if [ `grep dbenv /root/.bash_profile|wc -l` -eq 0 ]
		then
			echo "source $ENV" >> /root/.bash_profile
			echo "export PGUSER=sysdba" >> /root/.bash_profile
	else
		:
	fi
	
	source /root/.bash_profile
}

# 4.初始化数据库
init(){
        echo "$PASSWORD
$PASSWORD
$PASSWORD" > /tmp/.default_passwd
		while [[ ! $INT =~ [y,Y,n,N] ]]
		do
		read -p "数据库环境是否为分保环境【默认:n】: " INT
		log INFO "你选择需要初始化的数据库环境为：${INT:=n}"
		log INFO "开始初始化数据库实例……"
		case $INT in
			n|N)
				initdb -A scram-sha-256 -D $BPGDATA --pwfile=/tmp/.default_passwd
				echo 'host    all             all             0.0.0.0/0               scram-sha-256'>>$BPGDATA/pg_hba.conf
				;;
			y|Y)
				initdb -A sm3 -e sm4 -c "echo 12345678" -D $BPGDATA --pwfile=/tmp/.default_passwd
				echo 'host    all             all             0.0.0.0/0               sm3'>>$BPGDATA/pg_hba.conf
				;;
			*)
				log ERROR "只可输入y/n，请重新输入！"
				exit;
		esac
		done
		
        if [ $? -ne 0 ]; then
                rm -rf /tmp/.default_passwd
                exit
        fi
        rm -rf /tmp/.default_passwd
        hg_sslkeygen.sh $BPGDATA
        log INFO "初始化数据库实例成功。"
}


# 5.数据库参数配置
hgfile_set(){
log INFO "开始配置数据库参数……"
OS_MEM=`grep MemTotal /proc/meminfo | awk '{print $2}'`
let HG_MEM=$OS_MEM/1024/4

cat >> $BPGDATA/postgresql.auto.conf <<EOF
listen_addresses = '*'
port = '$PORT'
max_connections = 800
shared_buffers = '${HG_MEM}MB' 
checkpoint_completion_target = 0.8
log_destination = 'csvlog'
logging_collector = on
log_directory = 'hgdb_log'
log_filename = 'highgodb_%d.log'
log_rotation_age = '1d'
log_rotation_size = 0
log_truncate_on_rotation = on
log_statement = 'mod'
log_connections=on
log_disconnections=on
checkpoint_timeout='45min'
temp_buffers = '16MB'
work_mem = '8MB'
maintenance_work_mem='2GB'  
min_wal_size ='512MB'
max_wal_size ='4096MB'
effective_cache_size = '10GB'
archive_mode = on
archive_timeout = '45min'
archive_command = ' cp %p ${BACK_DIR}/archive/%f'
log_line_prefix = '%m [%p] %a %u %d %r %h'
shared_preload_libraries='pg_stat_statements'
compatible_db = 'oracle' 
EOF


log INFO "数据库参数配置成功。"

pg_ctl start -D $BPGDATA
if [ $? = 0 ]
then
	log INFO "数据库服务启动成功，运行状态正常！" 
else
	log ERROR "数据库服务启动失败，请检查启动的相关错误！"
fi

source /root/.bash_profile
}



# 6.创建软连接
ln_s(){
	ln -s $BPGDATA $PGHOME/data
	log INFO "软连接创建成功。"	
}

# 7.license授权
lic_set(){
	log INFO "开始进行license授权……"
	chmod 600 hgdb.lic
	cp hgdb.lic $PGHOME/etc/lic/
	log CMD "hg_lic"
	log INFO "license授权成功。"
}

# 8. 免密登录设置
login_set(){
if [ -f /root/.pgpass ]
	then
		:
else
cat > /root/.pgpass <<EOF
#hostname:port:database:username:password
localhost:$PORT:highgo:sysdba:$PASSWORD
localhost:$PORT:highgo:syssao:$PASSWORD
localhost:$PORT:highgo:syssso:$PASSWORD
EOF
fi

chmod 600 ~/.pgpass
}

# 9.审计设置
audit_set(){
	log INFO "开始关闭数据库审计……"
	psql highgo syssao -c "select set_audit_param('hg_audit','off');"
	log INFO "数据库审计关闭成功！"
}

# 10. 三权设置
secure_set(){
	echo "select set_secure_param('hg_sepofpowers','on');
select set_secure_param('hg_rowsecure','off');
select set_secure_param('hg_macontrol','min');
select set_secure_param('hg_showlogininfo','off');
select set_secure_param('hg_clientnoinput','0');
select set_secure_param('hg_idcheck.enable','on');
select set_secure_param('hg_idcheck.pwdlock','10');
select set_secure_param('hg_idcheck.pwdlocktime','8');
select set_secure_param('hg_idcheck.pwdpolicy','high');" > /tmp/.secure_param.sql
	log INFO "开始配置数据库安全参数……"
	psql -U syssso -d highgo -f /tmp/.secure_param.sql
	if [ $? -ne 0 ]; then
		rm -rf /tmp/.secure_param.sql
		exit
	fi
	rm -rf /tmp/.secure_param.sql
	pg_ctl restart
	log INFO "数据库安全参数配置完成！"
	psql highgo syssao -c "select show_audit_param();"
	psql highgo syssso -c "select show_secure_param();"
}

# 11.密码设置
passwd_set(){
	while [[ ! $p =~ [y,Y,n,N] ]]
	do
	read -p "是否更改数据库用户密码有效期为无限期【默认:y】: " p
	log INFO "是否更改数据库用户密码有效期为无限期【默认:y】，你选择${p:=y}"
	case "$p" in
		Y|y)
			log INFO "开始更改数据库密码有效期……"
			psql highgo syssso -c "select set_secure_param('hg_idcheck.pwdvaliduntil','0');"
			log INFO "数据库密码有效期已设置为无限期，重置数据库密码后生效。"
			;;
		N|n)
			read -p "请设置数据库密码有效期【默认：180天】：" yx
			log INFO "你设置的数据库密码有效期为 ${yx:=180} 天。"
			psql highgo syssso -c "select set_secure_param('hg_idcheck.pwdvaliduntil','$yx');"
			;;
		*)
			log ERROR "只可输入n或y，请重新输入！"
	esac
	done
	
	read -p "请设置 sysdba 用户新密码【默认：o2J#m@aZc1】：" DBAPASS
	log INFO "你设置的 sysdba 用户新密码为：${DBAPASS:=o2J#m@aZc1}"
	psql highgo sysdba -c "alter user sysdba password '$DBAPASS';"
	read -p "请设置 syssao 用户新密码【默认：pGY!@7x8rX】：" SAOPASS
	log INFO "你设置的 syssao 用户新密码为：${SAOPASS:=pGY!@7x8rX}"
	psql highgo syssao -c "alter user syssao password '$SAOPASS';"
	read -p "请设置 syssso 用户新密码【默认：i2ou@3Q1Y9】：" SSOPASS
	log INFO "你设置的 syssso 用户新密码为：${SSOPASS:=i2ou@3Q1Y9}"
	psql highgo syssso -c "alter user syssso password '$SSOPASS';"
	
cat > /root/.pgpass <<EOF
#hostname:port:database:username:password
localhost:$PORT:highgo:sysdba:$DBAPASS
localhost:$PORT:highgo:syssao:$SAOPASS
localhost:$PORT:highgo:syssso:$SSOPASS
EOF
}



# 12. 添加定时任务
cronadd(){
log INFO "开始部署定时备份任务……"
if [ -f $PGHOME/hgdb_backup.sh ]
	then
		:
	else
		cp hgdb_backup.sh $PGHOME/
fi

cat > /var/spool/cron/root <<EOF
10 00 * * * sh $PGHOME/hgdb_backup.sh
EOF

crontab -l
log INFO "定时备份任务部署成功。"

pg_ctl restart
source /root/.bash_profile
log INPUT "*************************************************************************" 
log INPUT "***********恭喜，数据库安装部署完成！请检查备份定时任务等。**************" 
log INPUT "*************************************************************************" 
}

# 13.主函数
main(){
	log
	check_disk
	def_var
	init
	hgfile_set
	login_set
	ln_s
	lic_set
	audit_set
	secure_set
	passwd_set
	cronadd
} 

# 14.执行
main
